'use strict'

const Controller = require('egg').Controller
const { decrypt } = require('../utils/cryptojs-aes')

class UserController extends Controller {
  // 登录
  async login() {
    const { ctx } = this
    const { username = '', password = '' } = ctx.request.body

    const userInfo = await ctx.model.User.findOne({ username })
    // 加密的'password'先加密比对数据库中的密码
    // 加密逻辑是前后端协定的
    const decodeEntryPassword = decrypt(password, username)
    const decodeRecordPassword = decrypt(userInfo ? userInfo.password : '', username)

    if (userInfo && decodeEntryPassword === decodeRecordPassword) {
      // 调用 rotateCsrfSecret 刷新用户的 CSRF token
      ctx.rotateCsrfSecret()
      // 设置 Session
      ctx.session.userId = userInfo._id
      ctx.body = { code: 2000, data: userInfo, msg: '登录成功' }
    } else {
      ctx.body = { code: 4001, data: null, msg: '账号或密码错误' }
    }
  }

  // 自动登录
  async autoLogin() {
    const { ctx } = this
    if (ctx.session.userId) {
      // 通过保存的session登录
      const userInfo = await ctx.model.User.findById(ctx.session.userId)

      if (!userInfo) {
        ctx.body = { code: 4002, data: null, msg: '用户id无效' }
      }

      // 调用 rotateCsrfSecret 刷新用户的 CSRF token
      ctx.rotateCsrfSecret()
      // 设置 Session
      ctx.session.userId = userInfo._id

      ctx.body = { code: 2000, data: userInfo, msg: '登录成功' }
    } else {
      ctx.body = { code: 4002, data: null, msg: 'session 无效' }
    }
  }

  // 退出登录
  async logout() {
    const { ctx } = this
    ctx.session.userId = null
    ctx.body = { code: 2000, data: null, msg: '已退出' }
  }

  // 当前用户详情
  async detail() {
    const { ctx } = this
    const id = ctx.session.userId

    const res = await ctx.model.User.findById(id)
    ctx.body = { code: 2000, data: res, msg: '用户信息查询成功' }
  }

  // 用户列表
  async list() {
    const { ctx } = this
    const res = await ctx.model.User.find()
    const total = await ctx.model.User.countDocuments()
    ctx.body = { code: 2000, data: { list: res, total }, msg: '用户列表查询成功' }
  }

  // 新建用户
  async create() {
    const { ctx } = this

    // 这里的'password'已经通过'username'加密
    const { username, password, ...rest } = ctx.request.body

    // 检测相同用户
    const hasSameAccount = await ctx.model.User.findOne({ username })
    if (hasSameAccount) {
      ctx.body = { code: 4002, data: null, msg: '用户名已经注册' }
      return
    }

    const res = await ctx.model.User.create({ username, password, ...rest })
    ctx.body = { code: 2000, data: res, msg: '用户注册成功' }
  }

  // 更新用户
  async update() {
    const { ctx } = this

    try {
      const updateFields = ctx.request.body
      const updatedAt = Date.now()
      await ctx.model.User.findById(ctx.session.userId).update({ ...updateFields, updatedAt })
    } catch (err) {
      ctx.body = { code: 5000, data: null, msg: '用户信息更新失败' }
      return
    }

    ctx.body = { code: 2000, data: null, msg: '用户信息更新成功' }
  }

  // 修改密码
  async updatePassword() {
    const { ctx } = this
    const { password, newPassword } = ctx.request.body

    try {
      const userInfo = await ctx.model.User.findById(ctx.session.userId)
      const decodeEntryPassword = decrypt(password, userInfo.username)
      const decodeRecordPassword = decrypt(userInfo ? userInfo.password : '', userInfo.username)

      if (decodeEntryPassword === decodeRecordPassword) {
        const updatedAt = Date.now()
        await ctx.model.User.findById(ctx.session.userId).update({ password: newPassword, updatedAt })
      } else {
        ctx.body = { code: 4001, data: { password, newPassword, decodeEntryPassword, decodeRecordPassword }, msg: '旧密码错误' }
        return
      }
    } catch (err) {
      ctx.body = { code: 5000, data: null, msg: '密码修改失败' }
      return
    }

    ctx.body = { code: 2000, data: null, msg: '密码修改成功' }
  }
}

module.exports = UserController
